May 1996

Removing a strangely named file

By August Mohr and Marco C. Mason

Sometimes you or your computer accidentally creates a file that has unusual characters in its name. Depending on the nature of the error and the application that created it, such a file might have control characters, quotes, tabs, or even new line characters within the name. Cleaning up such an error by removing the file can prove difficult, but it should be possible using one of the following techniques.

Filenames containing special characters

As you know, some characters have special meaning in the shell. These include the wildcard characters * and ?, quotation marks, parentheses, and the ampersand. If the filename contains characters like these that are special to the shell, all the characters of the filename may be visible in an ls listing, but you can't remove the file simply by typing the name as displayed.

Suppose you have a file named T&Bar\Vee in your directory that you want to remove. Your first impulse would be to use the rm command like this:

$ rm T&Bar\Vee

338
BarVee: not found

You can remove the file (or rename it with the mv command) by typing a backslash (\) before each special character. This tells the shell to treat the next character as a normal character. (This is why the \ didn't appear in the error message above; \V told the shell to treat the V as a V. In effect, the \ was ignored.) Since the backslash is a special character as well, a filename containing a backslash will need two of them. For example, to remove a file named T&Bar\Vee, you'll need to put a backslash before both the special characters & and \ in your rm command:

$ rm T\&Bar\\Vee

Names beginning with a dash

One common, but easy to deal with, case is a filename that begins with a dash (-), such as -foo. If you just try the obvious rm command, an error will occur:

$ rm -foo

rm: illegal option--0

rm: illegal option--0

usage: rm [-fiRr] file ...

This is because a dash introduces rm options, in this case, -f, -o, and another -o. There is a -f option to rm, but no -o, so rm complains. Even if it didn't, it still wouldn't remove your file named -foo. It would only set the specified options in preparation to deleting the file(s) specified, in this case, none.

There are many possible solutions, but the easiest one in this case is to precede the filename with ./. This simply specifies that the file is in the current directory. While this is what rm defaults to, adding the ./ to the start of the filename keeps rm from processing the filename as a set of switches because the dash is no longer the first character in the filename:

$ rm ./-foo

Names with non-printing characters

If the filename contains non-printing characters, such as control characters or spaces, that condition may show up in an ls listing that doesn't properly align in columns. If you're really unlucky, the filename contains the character sequence that clears your screen (e.g., the single character [Ctrl]L on the console). Every time the filename is printed, your screen clears.

One way of identifying the erroneous characters is to put the output of ls into a file and then examine the file with vi. Using the :set list command in vi will show where the lines end with a $ and let you identify embedded tabs and trailing spaces.

There are two options to the ls command that can also be helpful in identifying files with non-printing characters in their filenames. These are the -b and -q options. The -b option displays non-printing characters as three-digit octal values preceded by a \ character, and the -q flag causes them to be displayed as question marks. When you know where the non-printing characters are in the name, you can match those characters with shell wild card characters.

For instance, in a directory containing a file with the name foo^Lbar (with an embedded [Ctrl]L character), an ls command would just clear the screen, leaving just "bar" in the upper-left corner. Using ls -b would display it as foo\014bar and using ls -q would produce foo?bar. Knowing there is only one erroneous character, you could then remove the file with the command rm foo?bar (assuming no other files matched the foo?bar pattern).

You can also use the -i (interactive) flag for the rm command. Using the command rm -i * will prompt you for a y or n response for each file in the current directory. You simply respond with an n to each file except the ones you want to remove. You can use leading and trailing characters with the * to narrow the choices (e.g., rm -r f*r will offer you only files that begin with f and end with r).

You can copy all the valid files to another directory (not a subdirectory of the one with the problem). Then you can remove the troublesome file with the rest of the original directory using the command rm -r directory_name. Then you can re-create the directory and move the remaining files back.

If you're running OpenWin or the CDE environment, you can use the File Manager to delete the files. First, you must select the file(s) to delete. Then, in the OpenWin environment, select Delete from the Edit menu. In the CDE environment, choose Put in Trash from the Selected menu.

You can also use the find command to remove files using its -inum and -ok arguments. Using -inum followed by an inode number will match the file with that number. The -ok argument to find is similar to the -exec argument, except that it prompts you for confirmation before executing each command. Note that this wonít work well with filenames that have characters such as [Ctrl]L that affect the display.

To use find with the -inum option, first type ls -i. This will give you the inode numbers of all the files in the directory. Find the inode number of the problem file. Now, to delete the file, enter the command

$ find . -inum number -ok rm {} \;

where number is the inode number of the file you want to remove. You'll then be prompted to confirm whether you want to remove the file.

Names containing a slash

Another very special case occurs when the file contains an actual slash (/) in its name. This isn't supposed to happen--slashes separate the components of a name and are never supposed to occur within a name. In fact, you can't create such a file--the system won't let you. Nor can you remove such a file--the slash, no matter how you type it in, will be interpreted as a component separator.

Filenames with embedded slashes can only occur as a result of a catastrophic system failure. Extreme action is needed to remove them using the clri command. You can't use clri on a mounted file system, so this technique won't work on the root file system. See the next section, "Files Containing a / in Your Root File System," for additional instructions if your file exists in the root file system.

First, find the inode number using the ls -i command. Write this number down carefully. Next use the shutdown command to enter system maintenance mode. You should double-check that the file system in question has been unmounted. If it hasn't, use umount to unmount it. Clear the inode using the clri command.

Suppose for a moment that we have a file named gesoren/platz in our /var/x directory. Suppose further that the /var directory is the mount point for our /dev/dsk/c0t0d0s6 file system. Using ls -i, we find that the inode number of gesoren/platz is 2345. We put the system in system maintenance mode and unmount the /var file system. Now we can clear the inode with the command

# clri /dev/dsk/c0t0d0s6 2345

This command deallocates the inode and puts it on the free list. However, clri doesn't remove the entry from the directory. The directory entry that you couldn't remove is still pointing to the inode that's now on the free list. This is a potentially dangerous situation. Before you do anything else, run fsck on the affected file system. For the example above, run

# fsck -F ufs /dev/dsk/c0t0d0s6

and fsck will detect and repair the file system structure inconsistencies caused by our running the clri command. When it finds the directory entry that we cleared with clri, it will show some information like this:

# fsck -F ufs /dev/dsk/c0t0d0s6

** /dev/dsk/c0t0d0s6

** Currently Mounted on /a

** Phase 1 - Check Blocks and Sizes

** Phase 2 - Check Pathnames

UNALLOCATED I=2345 OWNER=root MODE=0

SIZE=0 MTIME=Dec 31 19:00 1969

NAME=/gesoren/platz

REMOVE?

Here, fsck is telling you that it found a directory entry for file /gesoren/platz using the unallocated inode numbered 2345. It wants to know if it should remove the directory entry. At the REMOVE? prompt, type y and press [Enter]. The fsck command will delete the directory entry and continue to scan your disk drive. Near the end, you'll get another warning:

** Phase 3 - Check Connectivity

** Phase 4 - Check Reference Counts

** Phase 5 - Check Cyl groups

FREE BLK COUNT(S) WRONG IN SUPERBLK

SALVAGE?

Now fsck is telling you that the number of free blocks calculated doesn't match the number of free blocks in the superblock. (The clri command didn't update the free block count in the superblock when it cleared the block.) It's asking if it can fix the count in the superblock. Again, type y and press [Enter]. Then fsck will finish fixing the errors on your drive:

22925 files, 394588 used, 1731393 free (3137 frags, 216032 blocks, 0.1% fragmentation)

***** FILE SYSTEM WAS MODIFIED *****

Warning: Running clri in multi-user mode, running clri on a mounted file system, or failing to run fsck immediately after running clri can cause file system corruption, leading to data loss.

Files containing a / in your root file system

Since the clri command works properly only on an unmounted file system, we need a way to run Solaris without mounting our root file system. For more information on this, see the article "Starting Solaris x86 in Single-User Mode" in the March issue of Inside Solaris.

You can use the basic technique described in that article to boot Solaris in maintenance mode from the CD-ROM. From there, you can execute the clri command to clear the specified inode and then run the fsck command as described in the previous section.

Conclusion

As with many things in Solaris, there are techniques you can use to accomplish a seemingly impossible task. In this article, we've tried to show you several ways you can solve the problem of removing files with unexpected characters in their names.


[Return to Index for Inside Solaris - May 1996 Issue]

Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.

Inside Solaris is a publication of The Cobb Group.

1-800-223-8720